package com.example.async.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
public class TransactionService {

    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    //  延迟注入自身代理对象、防止事务失效
    TransactionService selfProxy;
    @Lazy
    @Autowired
    public void setSelfProxy(TransactionService selfProxy) {
        this.selfProxy = selfProxy;
    }

    public void notSupported() {
        // 延迟注入自身代理对象、防止事务失效
        TransactionService selfProxy = (TransactionService) AopContext.currentProxy();
        // selfProxy.transform("alice", "bob", 100);
        transform("alice", "bob", 100);
    }

    @Transactional
    // 有事务就开启一个新事物的隔离级别，不能解决失效问题
    // 调用方没有启动一个事物
    // @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void transform(String from, String to, int amount) {
        TransactionService selfProxy = (TransactionService) AopContext.currentProxy();
        log.info("当前代理对象: {}", selfProxy);
        log.info("transform from {} to {} amount {}", from, to, amount);

        int row = jdbcTemplate.update(
                "update tbl_account set balance = balance - ? where name = ?", amount, from);

        // 模拟异常
        int i = 10 / 0;
        if (row == 0) {
            throw new RuntimeException("no such account: " + from);
        }
        row = jdbcTemplate.update(
                "update tbl_account set balance = balance + ? where name = ?", amount, to);
        if (row == 0) {
            throw new RuntimeException("no such account: " + to);
        }

    }

}
